﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;

namespace App_Code.Helpers
{
    public class VideoDetails
    {
        public string ErrorText { get; set; }
        public string Runtime { get; set; }
        public string Size { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public bool IsValid { get; set; }
    }

    public class VideoResult
    {
        public string Link { get; set; }
        public string MovieName { get; set; }
        public bool IsValid { get; set; }
        public VideoDetails VideoDetails { get; set; }

        public VideoResult(string link, bool isValid)
        {
            this.Link = Utils.LoopDecodeUrl(link);
            this.IsValid = isValid;

            if (isValid)
            {
                var start = this.Link.LastIndexOf("/");
                if (start != -1)
                    this.MovieName = this.Link.Substring(start+1);
            }
        }

        public VideoResult(string link, string movieName, bool isValid)
        {
            this.Link = Utils.LoopDecodeUrl(link);
            this.IsValid = isValid;
            this.MovieName = movieName;
        }
    }

    /// <summary>
    /// Summary description for Utils
    /// </summary>
    public class Utils
    {
        public static string LoopDecodeUrl(string baseUrl)
        {
            do
            {
                baseUrl = HttpUtility.UrlDecode(baseUrl);
            } while (baseUrl.Contains("%"));

            return baseUrl;
        }

        public static string DecodeUrl(string url)
        {
            try
            {
                var decodeUrl = LoopDecodeUrl(url);
                var urlByts = Convert.FromBase64String(decodeUrl);
                return LoopDecodeUrl(Encoding.Default.GetString(urlByts));
            }
            catch
            {
                return url;
            }
        }

        public static string EncodeUrl(string url)
        {
            var encodedUrl = HttpUtility.UrlEncode(url);
            if (encodedUrl != null)
            {
                var urlByts = Encoding.Default.GetBytes(encodedUrl);
                return HttpUtility.UrlEncode(Convert.ToBase64String(urlByts));
            }
            throw new Exception("url is empty");
        }

        public static string GetSiteUrl()
        {
            if (HttpContext.Current.Request.Url.OriginalString.IndexOf("?") != -1)
                return HttpContext.Current.Request.Url.OriginalString.Substring(0, HttpContext.Current.Request.Url.OriginalString.IndexOf("?"));
            return HttpContext.Current.Request.Url.OriginalString;
        }

        //public static string BuildUrl(HttpRequest request, int pluginId, string url, int mode)
        //{
        //    string siteUrl = request.Url.OriginalString.Substring(0, request.Url.OriginalString.IndexOf("?"));
        //    return string.Format("{0}?pluginId={1}&pluginLink={2}&pluginMode={3}", siteUrl, pluginId, EncodeUrl(url), mode);
        //}

        //public static string WrapUrl(HttpRequest request, int pluginId)
        //{
        //    return string.Format("{0}?pluginId={1}", request.Url, pluginId);
        //}

        public static string GetParam(NameValueCollection queryStringParams, string name, string defaultValue)
        {
            return queryStringParams[name] ?? defaultValue;
        }

        public static int GetParam(NameValueCollection queryStringParams, string name, int defaultValue)
        {
            return int.Parse(GetParam(queryStringParams, name, defaultValue.ToString()));
        }

        private static Cookie CreateMegaVideoCookieID(string userName, string password)
        {
            HttpWebResponse response = null;
            Stream stream = null;
            StreamReader reader = null;
            const int retries = 2;
            var count = 0;
            while (count < retries)
            {
                try
                {
                    const string url = "http://www.megavideo.com/?c=login";
                    var paramaters = string.Format("login=1&redir=1&username={0}&password={1}", userName, password); 
                    var request = (HttpWebRequest)WebRequest.Create(url);
                    request.CookieContainer = new CookieContainer();
                    request.Method = "POST";
                    request.ContentType = "application/x-www-form-urlencoded";

                    var bytes = Encoding.ASCII.GetBytes(paramaters);
                    request.ContentLength = bytes.Length;
                    var os = request.GetRequestStream();
                    os.Write(bytes, 0, bytes.Length);

                    request.Headers.Add("UserAgent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3");
                    request.Referer = "http://www.megavideo.com/?s=signup";

                    response = (HttpWebResponse)request.GetResponse();
                    response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
                    stream = response.GetResponseStream();

                    string buffer = "", line;

                    reader = new StreamReader(stream);

                    while ((line = reader.ReadLine()) != null)
                    {
                        buffer += line + "\r\n";
                    }

                    if (buffer.ToLower().Contains(userName.ToLower()))
                    {
                        var cookie = response.Cookies[0];
                        return cookie;
                    }
                }
                finally
                {
                    if (reader != null)
                        reader.Close();

                    if (stream != null)
                        stream.Close();

                    if (response != null)
                        response.Close();
                }
                count++;
            }

            return null;
        }

        public static string GetPage(string url, Encoding encoding)
        {
            return GetPage(url, encoding, string.Empty, string.Empty, null, null);
        }

        public static string GetPage(string url, Encoding encoding, Uri cookieUrl, Cookie cookie)
        {
            return GetPage(url, encoding, string.Empty, string.Empty, cookieUrl, cookie);
        }

        public static string GetPage(string url, Encoding encoding, string referer, string postParameters)
        {
            return GetPage(url, encoding, referer, postParameters, null, null);
        }

        public static string GetPage(string url, Encoding encoding, string referer, string postParameters, Uri cookieUrl, Cookie cookie)
        {
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en");
            request.Headers.Add("UserAgent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3");

            if (cookie != null)
            {
                request.CookieContainer = new CookieContainer();
                request.CookieContainer.Add(cookieUrl, cookie);
            }

            if(!string.IsNullOrEmpty(referer))
                request.Referer = referer;

            if(!string.IsNullOrEmpty(postParameters))
            {
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                var bytes = Encoding.ASCII.GetBytes(postParameters);
                request.ContentLength = bytes.Length;
                var os = request.GetRequestStream();
                os.Write(bytes, 0, bytes.Length);
            }

            return GetPage(request, encoding);
        }

        private static string GetPage(HttpWebRequest request, Encoding encoding)
        {
            WebResponse response = null;
            Stream stream = null;
            StreamReader reader = null;
            const int retries = 2;
            var count = 0;
            while (count < retries)
            {
                try
                {
                    response = request.GetResponse();
                    stream = response.GetResponseStream();

                    if (!response.ContentType.ToLower().StartsWith("text/"))
                        return null;

                    string buffer = "", line;

                    reader = new StreamReader(stream, encoding);

                    while ((line = reader.ReadLine()) != null)
                    {
                        buffer += line + "\r\n";
                    }

                    return buffer;
                }
                catch
                {
                    count++;
                    System.Threading.Thread.Sleep(1000);
                }
                finally
                {
                    if (reader != null)
                        reader.Close();

                    if (stream != null)
                        stream.Close();

                    if (response != null)
                        response.Close();
                }
            }

            throw new Exception("Can't process that type of file, please specify an HTML file URL.");
        }

        public static string GetMegaVideoPremium()
        {
            try
            {
                var cookie = CacheManager.Instance.GetData("MegaVideoCookie") as Cookie;
                if (cookie == null)
                {
                    cookie = CreateMegaVideoCookieID("Ofer_lz", "rubh01");
                    if (cookie == null) return string.Empty;
                    var pluginDBHandler = PluginDBHandler.Instance;
                    pluginDBHandler.InsertMegaVideoCookie(cookie.Value, cookie.Expires);
                    CacheManager.Instance.CacheData("MegaVideoCookie", cookie, cookie.Expires);
                }
                return cookie.Value;
            }
            catch(Exception ex)
            {
                Debug.WriteLine(string.Format("Error white trying to save megaupload cookie. Error {0}", ex.Message));
                return string.Empty;
            }
        }

        public static List<string> GetMovieLinks(string pageContent)
        {
            var movieLinks = new List<string>();
            if (VideoBBExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(VideoBBExtractor.GetMovieUrls(pageContent));
            }

            if (MytubeExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(MytubeExtractor.GetMovieUrls(pageContent));
            }

            if (VideozerExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(VideozerExtractor.GetMovieUrls(pageContent));
            }

            if (MegaVideoExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(MegaVideoExtractor.GetMovieUrls(pageContent));
            }

            if (TopdownMeExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(TopdownMeExtractor.GetMovieUrls(pageContent));
            }

            //if (MegaVideoExtractor.IsContainMegaUploadVideoLink(pageContent))
            //{
            //    var videoLink = MegaVideoExtractor.ConvertToMegaVideoLink(pageContent);
            //    return MegaVideoExtractor.GetMovieUrls(videoLink);
            //}
            return movieLinks;
        }

        /// <summary>
        /// Constructs a QueryString (string).
        /// Consider this method to be the opposite of "System.Web.HttpUtility.ParseQueryString"
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns>String</returns>
        public static String ConstructQueryString(NameValueCollection parameters)
        {
            return String.Join("&", (from string name in parameters
                                     select String.Concat(name, "=", HttpUtility.UrlEncode(parameters[name]))).ToArray());
        }

        public static bool IsBrokenLink(string url)
        {
            try
            {
                var http = (HttpWebRequest)WebRequest.Create(url);
                http.UserAgent = "Mozilla/9.0 (compatible; MSIE 6.0; Windows 98)";
                http.Method = "HEAD";
                http.Timeout = 10000;
                var httpresponse = (HttpWebResponse)http.GetResponse();

                return httpresponse.StatusCode != HttpStatusCode.OK;
            }
            catch (Exception)
            {
                return true;
            }
        }

        public static bool IsContainsHebrew(IEnumerable<char> text)
        {
            const int hebrewMinValue = 0x0590;
            const int hebrewMaxValue = 0x05FF;

            return text.Any(myChar => (myChar >= hebrewMinValue) && (myChar <= hebrewMaxValue));
        }       

        public static string CleanHtmlContent(string str)
        {
            str = str.Replace("\r", string.Empty);
            str = str.Replace("\n", string.Empty);
            str = str.Replace("\t", string.Empty);
            return str;
        }
    }
}